package com.quxiu.system.utils;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.quxiu.system.constant.BpmOperator;
import com.quxiu.system.domain.BpmCondition;
import org.apache.commons.collections4.CollectionUtils;

import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;

/**
 * 工作流条件工具
 */
public class BpmConditionUtil {
    /**
     * 条件计算
     * @param conditions 条件
     * @param formData 表单数据
     * @return
     */
    public static boolean calculate(List<List<BpmCondition>> conditions, JSONObject formData) {
        if (CollectionUtils.isEmpty(conditions)) {
            return true;
        }
        boolean result = false;
        for (List<BpmCondition> conditionList : conditions) {
            if (CollectionUtils.isNotEmpty(conditionList)) {
                boolean flag = true;
                for (BpmCondition condition : conditionList) {
                    String field = condition.getName();
                    String fieldValue = getFieldValue(formData, field);
                    String operator1 = condition.getOperator1();
                    String operator2 = condition.getOperator2();
                    String operator3 = condition.getOperator3();
                    String value1 = condition.getValue1();
                    String value2 = condition.getValue2();

                    switch (operator1) {
                        case BpmOperator.EQ:
                            flag = eq(fieldValue, value1);
                            break;
                        case BpmOperator.NE:
                            flag = en(fieldValue, value1);
                            break;
                        case BpmOperator.GT:
                            flag = gt(fieldValue, value1);
                            break;
                        case BpmOperator.GE:
                            flag = ge(fieldValue, value1);
                            break;
                        case BpmOperator.LT:
                            flag = lt(fieldValue, value1);
                            break;
                        case BpmOperator.LE:
                            flag = le(fieldValue, value1);
                            break;
                        case BpmOperator.IN:
                            flag = in(fieldValue, value1);
                            break;
                        case BpmOperator.INE:
                            flag = ine(fieldValue, value1);
                            break;
                        case BpmOperator.BT:
                            flag = bt(fieldValue, value1, value2, operator2, operator3);
                            break;
                        default:
                            break;
                    }
                    if (!flag) {
                        break;
                    }
                }
                if (flag) {
                    result = true;
                    break;
                }
            }
        }
        return result;
    }

    /**
     * 获取表单数据
     * @param formData 表单数据
     * @param field 字段
     * @return
     */
    private static String getFieldValue(JSONObject formData, String field) {
        if (formData != null) {
            return formData.getString(field);
        }
        return null;
    }

    /**
     * 等于
     * @param fieldValue 字段值
     * @param value1 值1
     * @return
     */
    private static boolean eq(String fieldValue, String value1) {
        if (fieldValue != null && value1 != null) {
            return fieldValue.equals(value1);
        }
        return false;
    }

    /**
     * 不等于
     * @param fieldValue 字段值
     * @param value1 值1
     * @return
     */
    private static boolean en(String fieldValue, String value1) {
        if (fieldValue != null && value1 != null) {
            return !fieldValue.equals(value1);
        }
        return false;
    }

    /**
     * 大于
     * @param fieldValue 字段值
     * @param value1 值1
     * @return
     */
    private static boolean gt(String fieldValue, String value1) {
        if (NumberUtil.isNumber(fieldValue) && NumberUtil.isNumber(value1)) {
            BigDecimal v1 = new BigDecimal(fieldValue);
            BigDecimal v2 = new BigDecimal(value1);
            return v1.compareTo(v2) > 0;
        }
        return false;
    }

    /**
     * 大于等于
     * @param fieldValue 字段值
     * @param value1 值1
     * @return
     */
    private static boolean ge(String fieldValue, String value1) {
        if (NumberUtil.isNumber(fieldValue) && NumberUtil.isNumber(value1)) {
            BigDecimal v1 = new BigDecimal(fieldValue);
            BigDecimal v2 = new BigDecimal(value1);
            return v1.compareTo(v2) >= 0;
        }
        return false;
    }

    /**
     * 小于
     * @param fieldValue 字段值
     * @param value1 值1
     * @return
     */
    private static boolean lt(String fieldValue, String value1) {
        if (NumberUtil.isNumber(fieldValue) && NumberUtil.isNumber(value1)) {
            BigDecimal v1 = new BigDecimal(fieldValue);
            BigDecimal v2 = new BigDecimal(value1);
            return v1.compareTo(v2) < 0;
        }
        return false;
    }

    /**
     * 小于等于
     * @param fieldValue 字段值
     * @param value1 值1
     * @return
     */
    private static boolean le(String fieldValue, String value1) {
        if (NumberUtil.isNumber(fieldValue) && NumberUtil.isNumber(value1)) {
            BigDecimal v1 = new BigDecimal(fieldValue);
            BigDecimal v2 = new BigDecimal(value1);
            return v1.compareTo(v2) <= 0;
        }
        return false;
    }

    /**
     * 包含任意一个
     * @param fieldValue 字段值
     * @param value1 值1
     * @return
     */
    private static boolean in(String fieldValue, String value1) {
        if (fieldValue != null && value1 != null) {
            List<String> v1 = getFieldValueList(fieldValue);
            List<String> v2 = getFieldValueList(value1);
            for (String s : v2) {
                if (v1.contains(s)) {
                    return true;
                }
            }
        }
        return false;
    }

    private static List<String> getFieldValueList(String value) {
        if (JSON.isValidArray(value)) {
            return JSON.parseArray(value, String.class);
        } else {
            return ListUtil.toList(value.split(","));
        }
    }

    /**
     * 完全包含
     * @param fieldValue 字段值
     * @param value1 值1
     * @return
     */
    private static boolean ine(String fieldValue, String value1) {
        if (fieldValue != null && value1 != null) {
            List<String> v1 = getFieldValueList(fieldValue);
            List<String> v2 = getFieldValueList(value1);
            if (CollectionUtils.isNotEmpty(v1) && CollectionUtils.isNotEmpty(v2)) {
                return new HashSet<>(v1).containsAll(v2);
            }
        }
        return false;
    }

    private static boolean bt(String fieldValue, String value1, String operator1, String value2, String operator2) {
        if (NumberUtil.isNumber(fieldValue) && NumberUtil.isNumber(value1)
                && NumberUtil.isNumber(value2) && operator1 != null && operator2 != null) {

            if (operator1.equals(BpmOperator.LT) && operator2.equals(BpmOperator.LT)) {
                return lt(fieldValue, value1) && lt(fieldValue, value2);
            } else if (operator1.equals(BpmOperator.LT) && operator2.equals(BpmOperator.LE)) {
                return lt(fieldValue, value1) && le(fieldValue, value2);
            } else if (operator1.equals(BpmOperator.LE) && operator2.equals(BpmOperator.LT)) {
                return le(fieldValue, value1) && lt(fieldValue, value2);
            } else if (operator1.equals(BpmOperator.LE) && operator2.equals(BpmOperator.LE)) {
                return le(fieldValue, value1) && le(fieldValue, value2);
            }
        }
        return false;
    }
}
